package Elementary_algorithm.Other;

import org.junit.Test;

import java.util.*;

/*
有效的括号
给定一个只包括 '('，')'，'{'，'}'，'['，']'的字符串 s ，判断字符串是否有效。
有效字符串需满足：
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1：
输入：s = "()"
输出：true
示例 2：
输入：s = "()[]{}"
输出：true
示例 3：
输入：s = "(]"
输出：false
示例 4：
输入：s = "([])"
输出：true

提示：
1 <= s.length <= 104
s 仅由括号 '()[]{}' 组成
作者：LeetCode
链接：https://leetcode.cn/leetbook/read/queue-stack/g9d0h/
 */
public class _05有效的括号 {

    @Test
    public void test() {
        System.out.println(isValid("){"));
    }

    //栈 + 模拟
    public boolean isValid(String s) {
        int n = s.length();
        /*if (n == 1)
            return false;*/
        //优化
        if (n % 2 == 1){
            return false;
        }
        ArrayList<Character> stack = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == '(' ){
                stack.add(')');
                continue;
            }else if (c == '{' ){
                stack.add('}');
                continue;
            }else if (c == '[' ){
                stack.add(']');
                continue;
            }
            if (stack.isEmpty() || stack.get(stack.size() - 1) != c) {
                return false;
            }
            if (stack.get(stack.size() - 1) == c) {
                stack.remove(stack.size() - 1);
            }
        }
        return stack.isEmpty();
    }

    //官解：栈
    /*
    作者：力扣官方题解
    链接：https://leetcode.cn/problems/valid-parentheses/solutions/373578/you-xiao-de-gua-hao-by-leetcode-solution/
     */
    class Solution {
        public boolean isValid(String s) {
            int n = s.length();
            if (n % 2 == 1) {
                return false;
            }

            Map<Character, Character> pairs = new HashMap<Character, Character>() {{
                put(')', '(');
                put(']', '[');
                put('}', '{');
            }};
            Deque<Character> stack = new LinkedList<Character>();
            for (int i = 0; i < n; i++) {
                char ch = s.charAt(i);
                if (pairs.containsKey(ch)) {
                    if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
                        return false;
                    }
                    stack.pop();
                } else {
                    stack.push(ch);
                }
            }
            return stack.isEmpty();
        }
    }


}
